use windows::{
    Win32::{
        Devices::Usb::GUID_DEVINTERFACE_USB_DEVICE,
        Foundation::{BOOL, HANDLE, HINSTANCE, HWND, LPARAM, WPARAM},
        System::{
            Com::{COINIT, CoInitializeEx, CoUninitialize},
            LibraryLoader::GetModuleHandleW,
        },
        UI::WindowsAndMessaging::{
            CreateWindowExW, DBT_DEVICEARRIVAL, DBT_DEVICEREMOVECOMPLETE,
            DBT_DEVTYP_DEVICEINTERFACE, DEV_BROADCAST_DEVICEINTERFACE_W, DEV_BROADCAST_HDR,
            DefWindowProcW, DestroyWindow, DispatchMessageW, GetMessageW, HCURSOR, HICON,
            PostMessageW, PostQuitMessage, RegisterClassW, RegisterDeviceNotificationW,
            TranslateMessage, UnregisterClassW, WINDOW_EX_STYLE, WINDOW_STYLE, WM_CLOSE,
            WM_DESTROY, WM_DEVICECHANGE, WM_QUIT, WNDCLASS_STYLES, WNDCLASSW,
        },
    },
    core::PCWSTR,
};

struct WindowsHotPlugger {
    hwnd: HWND,
    hinstance: HINSTANCE,
    class_name: Vec<u16>,
}

impl WindowsHotPlugger {
    unsafe fn cleanup(&self) {
        unsafe {
            // 销毁窗口处理
            if self.hwnd.0 != 0 {
                let result = DestroyWindow(self.hwnd);
                // 正确检查 BOOL 结果
                if result.is_ok() {
                    // 这里应该使用 .is_ok() 如果返回 Result 类型
                    println!("窗口销毁成功");
                } else {
                    let error = windows::core::Error::from_win32();
                    println!("窗口销毁失败: {}", error);
                }
            }

            // 注销窗口类处理
            if !self.class_name.is_empty() {
                let result = UnregisterClassW(PCWSTR(self.class_name.as_ptr()), self.hinstance);
                // 正确检查 BOOL 结果
                if result.is_ok() {
                    // 同理
                    println!("窗口类注销成功");
                } else {
                    let error = windows::core::Error::from_win32();
                    println!("窗口类注销失败: {}", error);
                }
            }

            // COM 库释放
            CoUninitialize();
            println!("COM 资源已释放");
        }
    }

    pub fn build() -> windows::core::Result<Self> {
        let state = unsafe {
            CoInitializeEx(None, COINIT::default())?;

            let class_name = "USB_MONITOR_CLASS\0".encode_utf16().collect::<Vec<_>>();
            let hinstance: HINSTANCE = GetModuleHandleW(None)?.into();

            let wnd_class = WNDCLASSW {
                hInstance: hinstance,
                lpfnWndProc: Some(std::mem::transmute(window_proc as *const ())),
                lpszClassName: PCWSTR(class_name.as_ptr()),
                style: WNDCLASS_STYLES::default(),
                cbClsExtra: 0,
                cbWndExtra: 0,
                hIcon: HICON::default(),
                hCursor: HCURSOR::default(),
                hbrBackground: Default::default(),
                lpszMenuName: PCWSTR::null(),
            };

            RegisterClassW(&wnd_class);

            let hwnd = CreateWindowExW(
                WINDOW_EX_STYLE::default(),
                PCWSTR(class_name.as_ptr()),
                PCWSTR("USB Monitor\0".encode_utf16().collect::<Vec<_>>().as_ptr()),
                WINDOW_STYLE::default(),
                0,
                0,
                0,
                0,
                None,
                None,
                hinstance,
                None,
            );

            register_device_notification(hwnd)?;
            Self {
                hwnd,
                hinstance,
                class_name,
            }
        };

        Ok(state)
    }

    pub fn init(&self) -> windows::core::Result<()> {
        let mut msg = Default::default();
        while unsafe { BOOL(GetMessageW(&mut msg, HWND::default(), 0, 0).0).as_bool() } {
            unsafe {
                TranslateMessage(&msg);
                DispatchMessageW(&msg);
            }
        }

        // 添加调试输出
        unsafe { self.cleanup() };
        Ok(())
    }
}

impl Drop for WindowsHotPlugger {
    fn drop(&mut self) {
        unsafe {
            std::thread::sleep(std::time::Duration::from_secs(5));
            PostMessageW(self.hwnd, WM_CLOSE, WPARAM(0), LPARAM(0)).unwrap();
        }
    }
}

unsafe extern "system" fn window_proc(
    hwnd: HWND,
    msg: u32,
    wparam: WPARAM,
    lparam: LPARAM,
) -> isize {
    match msg {
        WM_DEVICECHANGE => {
            let event_type = wparam.0 as u32;
            let header = lparam.0 as *const DEV_BROADCAST_HDR;

            unsafe {
                if !header.is_null()
                    && (*header).dbch_devicetype
                        == windows::Win32::UI::WindowsAndMessaging::DEV_BROADCAST_HDR_DEVICE_TYPE(
                            DBT_DEVTYP_DEVICEINTERFACE.0 as u32,
                        )
                {
                    let dev_interface = lparam.0 as *const DEV_BROADCAST_DEVICEINTERFACE_W;

                    // 获取设备路径
                    let path = {
                        let ptr = (*dev_interface).dbcc_name.as_ptr() as *const u16;
                        let mut len = 0;
                        while *ptr.add(len) != 0 {
                            len += 1;
                        }
                        String::from_utf16_lossy(std::slice::from_raw_parts(ptr, len as usize))
                    };

                    match event_type {
                        DBT_DEVICEARRIVAL => println!("[USB Inserted] {}", path),
                        DBT_DEVICEREMOVECOMPLETE => println!("[USB Removed]"),
                        _ => (),
                    }
                }
            }
            1 // 必须返回1表示处理成功
        }
        WM_QUIT => {
            unsafe { PostQuitMessage(0) };
            0
        }
        WM_DESTROY => {
            println!("[DEBUG] 收到 WM_DESTROY 消息");
            unsafe { PostQuitMessage(0) };
            0
        }
        _ => unsafe { DefWindowProcW(hwnd, msg, wparam, lparam).0 },
    }
}

unsafe fn register_device_notification(hwnd: HWND) -> windows::core::Result<()> {
    let dbdi = DEV_BROADCAST_DEVICEINTERFACE_W {
        dbcc_size: std::mem::size_of::<DEV_BROADCAST_DEVICEINTERFACE_W>() as u32,
        dbcc_devicetype: DBT_DEVTYP_DEVICEINTERFACE.0,
        dbcc_classguid: GUID_DEVINTERFACE_USB_DEVICE,
        dbcc_reserved: 0,
        dbcc_name: [0; 1],
    };

    // 使用嵌套的 unsafe 块明确标识 unsafe 操作
    let result = unsafe {
        RegisterDeviceNotificationW(
            HANDLE(hwnd.0 as isize),
            &dbdi as *const _ as *const _,
            windows::Win32::UI::WindowsAndMessaging::DEVICE_NOTIFY_WINDOW_HANDLE,
        )
    };

    result.map(|_| ())
}

pub type Result<T> = core::result::Result<T, Error>;
pub type Error = Box<dyn std::error::Error>; // For early dev.

fn main() -> Result<()> {
    let handler = WindowsHotPlugger::build()?;
    handler.init()?;
    Ok(())
}
